#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
 
/*app名称与要打开的设备节点*/
int main(int argc, char **argv)
{
    int fd ; // 文件句柄
    int err ; // ioctl的错误信息
    int len ; // 获取设备evbit的大小
    int i;
    int byte; // 字节
    int bit; // 位
    struct input_id id; // 存放设备信息的对象
    unsigned int evbit[2]; // 存放设备evbit数据的数组
    char *ev_names[] = {// 定义一个指针数组，存放支持事件的名称
		"EV_SYN ",
		"EV_KEY ",
		"EV_REL ",
		"EV_ABS ",
		"EV_MSC ",
		"EV_SW	",
		"NULL ",
		"NULL ",
		"NULL ",
		"NULL ",
		"NULL ",
		"NULL ",
		"NULL ",
		"NULL ",
		"NULL ",
		"NULL ",
		"NULL ",
		"EV_LED ",
		"EV_SND ",
		"NULL ",
		"EV_REP ",
		"EV_FF	",
		"EV_PWR ",
		};
 
 
    /*判断传参是否正确是否*/
    if(argc != 2)
    {
        printf("Usage:%s <dev>\r\n", argv[0]);
        return -1;
    }
 
    /*打开设备节点*/
    fd = open(argv[1], O_RDWR);
    if(fd < 0)
    {
        printf("%s err\r\n", argv[1]);
        return -1;
    }
 
    /*获取设备信息并打印*/
    err = ioctl(fd , EVIOCGID , &id);
    if (err == 0)
    {
    /*  EVIOCGID获取的信息
        __u16 bustype;//总线类型
        __u16 vendor;//厂商
        __u16 product;
        __u16 version;
    */
        printf("bustype = 0x%x\n" , id.bustype);
        printf("vendor = 0x%x\n" , id.vendor);
        printf("product = 0x%x\n" , id.product);
        printf("version = 0x%x\n" , id.version);
    }
 
    /*获取设备evbit，即支持哪些事件*/
    len = ioctl(fd, EVIOCGBIT(0,sizeof(evbit)) , &evbit);
    if (len > 0 && len < sizeof(evbit))
    {
        printf("support ev type\n");
        for(i = 0; i < len; i++)
        {
            byte = ((unsigned char*)evbit)[i];// 将evbit中的一个字节的数据写入byte
            for(bit = 0 ; bit<8 ; bit++ ) 
            {
                if(byte & (1<<bit))
                {// 判断byte中哪一位是等于1的
                    printf("%s" , ev_names[i*8+bit]);// 打印出对应位的信息
                }
            }
        }
        printf("\n");
    }
    return 0;
}